var Calendar = new Class({
    date : null,
    onSelect : function(day){},
    DOM : {
        body :null,
        title:null,
        table :null
    },
    initialize : function(date){
        this.date = date === null ? new Date() : Date.parse(date);
        this.today = new Date();
    },

    // 取消选择日期
    unselect   : function(){
        this.DOM.table.getElements('a.selected').each(function(ele){
            ele.removeClass('selected');
        });
    },

    // 选择指定日期
    select    : function(days){
        for (var i = 0; i < days.length; i++) {
            this.selectItem(days[i]);
        }
    },

    getDayLink    : function(day){
        return this.DOM.table.getElement('a.selectable[date=' + day.format('%y%m%d') + ']');
    },

    loadCalendar : function(){
        var self = this;
        this.DOM.body = new Element('div', {
            'class': 'calendar-body'
        });
        this.DOM.title = new Element('h3');
        this.DOM.table = new Element('table');

        // 日历界面框架
        this.DOM.body.adopt(this.DOM.title, this.DOM.table);
        this.DOM.body.set({
            id : 'calendar-' + this.date.format('%y%m%d')
        });
        this.DOM.title.set({
            id : this.DOM.body.id + '-title',
            html : this.date.format('%Y年%m月')
        });
        this.DOM.table.set({
            id : this.DOM.body.id + '-table'
        });
        this.DOM.table.set('html', '<tr class="calendar-table-header"><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</h><th>六</th></tr>');

        // 填充日期项目
        var firstdayOfMonth = this.date.clone().set('date', 1);
        var firstdayOfCalendar = firstdayOfMonth.decrement('day', firstdayOfMonth.get('day'));
        var tbody = new Element('tbody');
        tbody.inject(this.DOM.table);
        for (var i = 0; i < 42; i++) {
            var currentDay = firstdayOfCalendar.clone().increment('day', i);
            if (i % 7 == 0) {
                var row = new Element('tr', {
                    'class': 'calendar-table-row'
                });
                
                row.inject(tbody);
            }

            var td = new Element('td');
            var linkClass = (currentDay.get('month') == this.date.get('month')) ? 'selectable' : 'unselectable';
            if (this.today - currentDay < 0) {
                linkClass = 'unselectable';
            }
            
            var link = new Element('a', {
                id    : 'calendar-day-' + currentDay.format('%y%m%d'),
                href  : 'javascript:void(0);',
                html  : currentDay.get('date'),
                'date': currentDay.format('%y%m%d'),
                events : {
                    click : function(e){
                        if(this.hasClass('selectable')){
                            self.onSelect(this.day);
                            self.selectItem(this.day);
                        }
                    }
                }
            });
            if (this.today.toDateString() == currentDay.toDateString()) {
                linkClass = 'unselectable';
                link.addClass('today unselectable');
                link.setStyles({color : '#000'});
            }
            link.addClass(linkClass);
            link.day = currentDay;
            link.inject(td);
            td.inject(row);
        }
    },
    selectItem : function(day){
        var dayLink =  this.getDayLink(day);
        if (dayLink) {
            dayLink.removeClass('selected').addClass('selected');
        }
    },
    show : function(body){
        this.loadCalendar();
        if (!body) {
            body = document.body;
        }
        this.DOM.body.inject(body);
    },
    close : function(){
        this.DOM.body.destroy();
        delete this;
    }
});
var DateRangeSelector = new Class({
    DOM : { body: null },
    sender : null,
    format : '%y/%m/%d',
    field : null,
    shortcuts : [
        {text : '昨天', dates: function(){
            var today = new Date();

            return [today.clone().decrement('day', 1), today.clone().decrement('day', 1)];
        }},
        {text : '本周', dates: function(){
            var today = new Date();

            return [today.clone().decrement('day', today.get('day')), today.clone().decrement('day', 1)];
        }},
        {text : '本月', dates: function(){
            var today = new Date();

            return [today.clone().decrement('day', today.get('date') - 1), today.clone().decrement('day', 1)];
        }},
        {text : '本季', dates: function(){
            var today = new Date();
            var currentMonth = today.get('month');
            //据本季度开始相差的月数
            var diffMonth = currentMonth % 3;
            //本季度开始的第一天
            var quarter = new Date(today.get('year'), currentMonth - diffMonth, 1);
            return [quarter, today.clone().decrement('day', 1)];
        }}
    ],
    date : null,
    calendars : [],
    selected  : {related : null, range : { start: null, end: null}},
    initialize : function(field, currentDate){
        this.date = Date.parse(currentDate);
        this.field = field;
    },
    loadCalendars : function(currentDate){
        // 初始化及配置
        var self = this;
        for (var i = 0; i < 3; i++) {
            var cale = new Calendar(currentDate.clone().decrement('month', i));
            cale.onSelect = function(day){
                self.change(day);
            }
            this.calendars[i] = cale;
        };
        this.calendars.reverse();
    },
    loadSelector : function(){
        var self = this;
        this.DOM.body = new Element('div', {
            'class': 'dateRangeSelector'
        });
        var table  = new Element('table', {
            'class': 'calendarArea',
            border : 0
        });
        var tbody = new Element('tbody');
        var tr = new Element('tr', {
            'class': 'selector-body'
        });
        var trActionCol = new Element('tr');
        var actionCol = new Element('td', {
            valign: 'top',
            'class': 'actions',
            html: '<h3>快速选择:</h3>',
            colspan: 5
        });
        var ul = new Element('ul', {
            'class': 'shortcuts'
        });
        for (var i = 0; i < this.shortcuts.length; i++) {
            var dates = this.shortcuts[i].dates();
            var scInfo = this.shortcuts[i];
            var shortcut = new Element('li');
            var shortcutLink  = new Element('a', {
                'href' : 'javascript:;',
                'html' : scInfo.text
            });
            shortcutLink.getDates = this.shortcuts[i].dates;
            shortcutLink.addEvent('click', function(){
                self.selectDates(this.getDates());
            });
            shortcutLink.inject(shortcut);
            shortcut.inject(ul);
        }
        ul.inject(actionCol);
        var prev = new Element('td',{
            'class': 'arrow-td'
        });
        var prevLink = new Element('a', {
            href:'javascript:;',
            id : 'preLink',
            'class': 'prelink',
            events : {
                click:function(){
                    self.prevMonth();
                }
            }
        });
        prevLink.inject(prev);
        var next = new Element('td',{
            'class': 'arrow-td'
        });
        var nextLink = new Element('a', {
            href:'javascript:;',
            id : 'nextLink',
            'class': 'nextlink',
            events : {
                click:function(){
                    self.nextMonth();
                }
            }
        });
        nextLink.inject(next);
        //actionCol.inject(tr);
        actionCol.inject(trActionCol);
        prev.inject(tr);
        for (var i = 0; i < 3; i++) {
            var calendarCol = new Element('td', {
                'class' : 'calendar-col'
            });
            calendarCol.inject(tr);
        }
        next.inject(tr);
        tr.inject(tbody);
        trActionCol.inject(tbody);
        tbody.inject(table);
        table.inject(this.DOM.body);
        var applyButton = new Element('button', {
            'html' : '应用',
            'events' : {
                click : function(){
                    if (self.selected.range.end === null) {
                        alert('请选择结束日期');
                        return;
                    }
                    self.field.value = self.selected.range.start.format(self.format) + ' to ' + self.selected.range.end.format(self.format);
                    self.close();
                }
            }
        });
        var cancelButton = new Element('button', {
            'html' : '取消',
            'events' : {
                click : function(){
                    self.close();
                }
            }
        });
        cancelButton.inject(actionCol);
        applyButton.inject(actionCol);
        this.showCalendars();
        this.DOM.body.setStyles({
            left : this.sender.getLeft(),
            top : this.sender.getTop() + 30
        });
        this.DOM.body.inject(document.body);
    },
    showCalendars : function(){
        this.loadCalendars(this.date);
        for (var i = 0; i < this.calendars.length; i++) {
            this.calendars[i].show(this.DOM.body.getElements('td.calendar-col')[i]);
        }
        // 判断是否显示下一个月
        var self = this;
        var today = new Date();
        var nextLink = this.DOM.body.getElement('a[id=nextLink]');
        if (this.date.get('year') >= today.get('year') && this.date.get('month') >= today.get('month')) {
            nextLink.removeClass('nextlink');
            nextLink.addClass('disable-nextlink');
            nextLink.removeEvents();
        } else {
            nextLink.removeClass('disable-nextlink');
            nextLink.addClass('nextlink');
            nextLink.removeEvents();
            nextLink.addEvent('click', function () {
                self.nextMonth();
            });
        }
        //显示已选择的日期
        if (this.selected.range.start != null && this.selected.range.end != null) {
            this.selectDates([this.selected.range.start, this.selected.range.end]);
            
        } else if (this.selected.range.start != null) {
            this.change(this.selected.range.start);
        }
    },
    show : function(){
        var self = this;
        if (this.DOM.body === null) {
            this.loadSelector();
        }
        this.parseDefaultDate();
        this.DOM.body.show();
    },
    parseDefaultDate : function () {
        if ($defined(this.sender.value) === false) {
            return false;
        }
        var date = this.sender.value.split(' to ');
        var start = new Date(date[0]);
        this.selectDates([new Date(date[0]), new Date(date[1])]);
        
    },
    close : function(){
        /*for (var i = 0; i < this.calendars.length; i++) {
            this.calendars[i].close();
        }*/
        this.DOM.body.hide();
    },
    nextMonth : function(){
        for (var i = 0; i < this.calendars.length; i++) {
            this.calendars[i].close();
        }
        this.calendars = [];
        this.date = this.date.increment('month', 1);
        this.showCalendars();
    },
    prevMonth : function(){
        for (var i = 0; i < this.calendars.length; i++) {
            this.calendars[i].close();
        }
        this.calendars = [];
        this.date = this.date.decrement('month', 1);
        this.showCalendars();
    },
    selectDates : function(dates){
        this.selected.related = null;
        this.selected.range.start = this.selected.range.end = null;
        this.change(dates[0]);
        this.change(dates[dates.length - 1]);
    },
    change : function(day){
        if (this.selected.related !== null && this.selected.related.diff(day) > 0) {
            this.selected.range.start = this.selected.related;
            this.selected.range.end   = day;
        } else {
            this.selected.range.start = day;
            this.selected.range.end   = this.selected.related;
        }

        this.selected.related = day;

        // 计算选中区间
        var length = this.selected.range.end === null ? 0 : this.selected.range.start.diff(this.selected.range.end);
        var selectedDays = [];
        for (var i = 0; i <= length; i++) {
            selectedDays.push(this.selected.range.start.clone().increment('day', i));
        }

        // 重新渲染
        for(var i = 0; i < this.calendars.length; i++){
            this.calendars[i].unselect();
            this.calendars[i].select(selectedDays);
        }
    }
});
